<?php
/**
 * Extend the PeopleSession class to support Zend_Session
 *
 * @author @@AUTHOR@@
 * @copyright @@AUTHOR@@ @@YEAR@@
 * @version @@VERSION@@
 * @package Extensions
 * @subpackage DbSession
 * @license  @@LICENCE_URL@@ @@LICENCE@@
 *
 * $Id: People.Class.DbSessionSession.php 322 2008-10-11 13:03:00Z dinoboff $
 * $HeadURL: http://vanilla-friends.googlecode.com/svn/trunk/DbSession/library/People/People.Class.DbSessionSession.php $
 */

if (!defined('IN_VANILLA')) exit();

/**
 * @global Context $Context
 */
global $Configuration;
include_once $Configuration['LIBRARY_PATH'] . '/People/People.Class.Session.php';
include_once 'Zend/Session.php';
include_once 'Zend/Session/Namespace.php';
include_once 'Zend/Session/SaveHandler/DbTable.php';
include_once 'Zend/Db.php';
include_once 'Zend/Db/Table/Abstract.php';

/**
 * Add Zend_Session support to People session
 *
 * @package Extensions
 * @subpackage DbSession
 */
class DbSessionSession extends PeopleSession  {

	/**
	 * @var Zend_Session_Namespace
	 */
	private $_Session;

	function Destroy() {
		Zend_Session::destroy();
		$this->UserID = 0;
		$this->User->Clear();
	}

	/**
	 * Return session variable
	 *
	 * @param string $Name
	 * @param string $Value $DataType int|bool|array|string
	 * @return int|boolean|array|string $Value
	 */
	function GetVariable($Name, $DataType = 'bool') {
		$Value = null;
		if (isset($this->_Session->$Name)) {
			$Value = $this->_Session->$Name;
		}

		if ($DataType == 'int') {
			return ForceInt($Value, 0);
		} else if ($DataType == 'bool') {
			return ForceBool($Value, 0);
		} else if ($DataType == 'array') {
			return ForceArray($Value, array());
		} else {
			return ForceString($Value, '');
		}
	}

	function RegenerateId() {
		Zend_Session::regenerateId();
	}

	/**
	 * @see PeopleSession::SetVariable()
	 *
	 * @param string $Name
	 * @param int|boolean|array|string $Value
	 */
	function SetVariable($Name, $Value) {
		$this->_Session->$Name = $Value;
	}

	/**
	 * @see PeopleSession::Start()
	 *
	 * @param Context $Context
	 * @param DbSessionAuthenticator $Authenticator
	 * @param int $UserID
	 */
	function Start(&$Context, $Authenticator,  $UserID = '0') {
		$this->_StartSession($Context);

		// If the UserID is not explicitly defined (ie. by some vanilla-based login module),
		// retrieve the authenticated UserID from the Authenticator module.
		$this->UserID = ForceInt($UserID, 0);
		if ($this->UserID == 0) $this->UserID = $Authenticator->GetIdentity();

		// Now retrieve user information
		$this->SetUserDetails($Context);
	}

	/**
	 * @param Context $Context
	 * @param Boolean $Reload
	 */
	function SetUserDetails($Context, $Reload=0) {
		$User = false;
		if ($this->UserID > 0) {
			$LastSessionUpdate = $this->GetVariable('DB_SESSION_SERIALIZED_USER_LAST_UPDATE', 'int');
			$LastSystemUpdate = ForceInt(@$Context->Configuration['DBSESSION_LAST_UPDATE'], 0);
			if (!$Reload
				&& $LastSessionUpdate > $LastSystemUpdate
			) {
				$SerializedUser = $this->GetVariable('DB_SESSION_SERIALIZED_USER', 'string');
				$User = @unserialize($SerializedUser);
			}

			if (!$User || !($User instanceof User)) {
				$UserManager = $Context->ObjectFactory->NewContextObject($Context, 'UserManager');
				$User = $UserManager->GetSessionDataById($this->UserID);
				if ($User) {
					$this->SetVariable('DB_SESSION_SERIALIZED_USER', @serialize($User));
					$this->SetVariable('DB_SESSION_SERIALIZED_USER_LAST_UPDATE', mktime());
				}
			}
		}

		if (!$User) {
			$User = $Context->ObjectFactory->NewContextObject($Context, 'User');
			$User->Clear();
		}
		$this->User = $User;
	}

	/**
	 * Take care of Zend_Session settings
	 * @param Context $Context
	 */
	function _StartSession($Context) {
		$Adapter = ForceString(@$Context->Configuration['DBSESSION_ZEND_DB_ADAPTER'], 'Pdo_Mysql');
		$Db = Zend_Db::factory($Adapter, array(
		    'host'        => $Context->Configuration['DATABASE_SESSION_HOST'],
		    'username'    => $Context->Configuration['DATABASE_SESSION_USER'],
		    'password'    => $Context->Configuration['DATABASE_SESSION_PASSWORD'],
		    'dbname'    => $Context->Configuration['DATABASE_SESSION_NAME']
		));
		Zend_Db_Table_Abstract::setDefaultAdapter($Db);

		$TableConfig = array(
		    'name'           => $Context->DatabaseTables['DbSession_Session'],
		    'primary'        => $Context->DatabaseColumns['DbSession_Session']['SessionID'],
		    'modifiedColumn' => $Context->DatabaseColumns['DbSession_Session']['Modified'],
		    'dataColumn'     => $Context->DatabaseColumns['DbSession_Session']['Data'],
		    'lifetimeColumn' => $Context->DatabaseColumns['DbSession_Session']['LifeTime']
		);
		Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($TableConfig));

		$SessionOptions = array(
			'cookie_domain' => $Context->Configuration['COOKIE_DOMAIN'],
			'cookie_path' => $Context->Configuration['COOKIE_PATH']
		);
		if ($Context->Configuration['SESSION_NAME']) {
			$SessionOptions[] = $Context->Configuration['SESSION_NAME'];
		}
		Zend_Session::setOptions($SessionOptions);

		$this->_Session = new Zend_Session_Namespace('VANILLA_CORE');
	}

}
